package com.yupi.springbootinit.service.execution;

import com.yupi.springbootinit.common.ErrorCode;
import com.yupi.springbootinit.constant.CommonConstant;
import com.yupi.springbootinit.constant.FileConstant;
import com.yupi.springbootinit.exception.BusinessException;
import com.yupi.springbootinit.exception.ThrowUtils;
import com.yupi.springbootinit.manager.AiManager;
import com.yupi.springbootinit.model.entity.Chart;
import com.yupi.springbootinit.model.enums.GenChartStrategyEnum;
import com.yupi.springbootinit.model.vo.BiResponse;
import com.yupi.springbootinit.service.ChartService;
import com.yupi.springbootinit.service.GenChartStrategy;
import com.yupi.springbootinit.utils.ChartUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 线程池生成
 * @TODO 反向压力
 */
@Slf4j
@Component(value = "gen_thread_pool")
public class GenChartThreadPool implements GenChartStrategy {

    @Resource
    private ChartService chartService;

    @Resource
    private AiManager aiManager;

    @Resource
    // 自动注入一个线程池实例
    private ThreadPoolExecutor threadPoolExecutor;

    @Override
    public BiResponse executeGenChart(Chart chartEntity) {
        try {
            CompletableFuture.runAsync(() -> {
                Chart genChartEntity = new Chart();
                genChartEntity.setId(chartEntity.getId());
                genChartEntity.setStatus(FileConstant.RUNNING);
                boolean b = chartService.updateById(genChartEntity);
                // 处理异常
                ThrowUtils.throwIf(!b, new BusinessException(ErrorCode.SYSTEM_ERROR, "修改图表状态信息失败 " + chartEntity.getId()));
                // 获取CSV
                // 构造用户输入
                String userInput = ChartUtil.buildUserInput(chartEntity);
                /* 较好的做法是在系统（模型）层面做预设效果一般来说，会比直接拼接在用户消息里效果更好一些。*/
                // 调用AI，并获取返回值
                String result = aiManager.doChat(CommonConstant.BI_MODEL_ID, userInput);
                String[] split = result.split("【【【【【");
                // 第一个是 空字符串
                if (split.length != 3) {
                    throw new BusinessException(ErrorCode.SYSTEM_ERROR, "AI 生成错误!");
                }
                // 图表代码
                String genChart = split[1].trim();
                // 分析结果
                String genResult = split[2].trim();
                String compressJson = ChartUtil.compressJson(genChart);
                // 更新数据
                chartEntity.setChartData(null);
                chartEntity.setStatus(FileConstant.SUCCEED);
                chartEntity.setGenChart(compressJson);
                chartEntity.setGenResult(genResult);
                chartEntity.setStrategy(GenChartStrategyEnum.GEN_THREAD_POOL.getValue());
                boolean updateGenResult = chartService.updateById(chartEntity);
                // boolean syncResult = chartService.syncChart(chartEntity, compressJson, genResult);
                // ThrowUtils.throwIf(!updateGenResult && syncResult, ErrorCode.SYSTEM_ERROR, "生成图表保存失败!");
                ThrowUtils.throwIf(!updateGenResult, ErrorCode.SYSTEM_ERROR, "生成图表保存失败!");
            }, threadPoolExecutor);
        } catch (BusinessException e) {
            // 更新状态信息
            Chart updateChartResult = new Chart();
            updateChartResult.setId(chartEntity.getId());
            updateChartResult.setStatus(FileConstant.FAILED);
            updateChartResult.setExecMessage("execMessage2");
            boolean updateResult = chartService.updateById(updateChartResult);
            // 补偿积分
            // pointService.sendCompensateMessage(chartEntity.getUserId(), PointChangeEnum.GEN_CHART_FAILED_ADD);
            // 记录调用结果: 这里的recordLog不会与上面的冲突,如果上面的执行了那么图表的生成结果一定是成功,不会执行到这里
            // logService.recordLog(chartEntity);
            if (!updateResult) {
                log.info("更新图表FAILED状态信息失败 , chatId:{}", updateChartResult.getId());
            }
            // 抛出异常进行日志打印
            // throw new GenChartException(chartEntity.getId(), e);
        }
        BiResponse biResponse = new BiResponse();
        biResponse.setChartId(chartEntity.getId());
        return biResponse;
    }
}